package com.rzjm.exercise.common.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 日期处理
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils{
    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final static SimpleDateFormat sdfTime1 = new SimpleDateFormat("MM-dd HH:mm:ss");
    private final static SimpleDateFormat sdfTimes = new SimpleDateFormat("yyyyMMddHHmmss");
    private final static SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
    private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
    private final static SimpleDateFormat sdfDayMonth = new SimpleDateFormat("yyyy-MM");
    private final static SimpleDateFormat sdfSimpleTime = new SimpleDateFormat("HH:mm:ss");
    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    private final static SimpleDateFormat sdfSimpleTime1 = new SimpleDateFormat("HH:mm");
    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 获取yyyyMMddHHmmss格式
     * @return
     */
    public static String getMonthStr(Date date) {
        return sdfDayMonth.format(date);
    }



    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     * @return
     */
    public static String getSimpleTime1(Date date) {
        return sdfSimpleTime1.format(date);
    }


    public static final String getLocalDateTime(LocalDateTime date) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS);
        return dtf.format(date);
    }
    public static Date getDateByDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        if (days > 0) {
            calendar.set(Calendar.HOUR_OF_DAY,23);
            calendar.set(Calendar.MINUTE,59);
            calendar.set(Calendar.SECOND,59);
        }else{
            calendar.set(Calendar.HOUR_OF_DAY,0);
            calendar.set(Calendar.MINUTE,0);
            calendar.set(Calendar.SECOND,0);
        }
        return calendar.getTime();
    }


    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     * @param one 时间参数 1 格式：1990-01-01 12:00:00
     * @param two 时间参数 2 格式：2009-01-01 12:00:00
     * @return String 返回值为：xx天xx小时xx分xx秒
     */
    public static String getDistanceTimeByDate(Date one, Date two,int isShowSecond) {
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {
//			one = df.parse(str1);
//			two = df.parse(str2);
            long time1 = one.getTime();
            long time2 = two.getTime();
            long diff ;
            if(time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String ret = "";
        if(day > 0){
            ret = day + "天" + hour + "小时" + min + "分" + (isShowSecond == 1 ? sec + "秒":"") ;
        } else if(day == 0 && hour > 0){
            ret = hour + "小时" + min + "分" + (isShowSecond == 1 ? sec + "秒":"") ;
        } else if(day == 0 && hour == 0 && min > 0){
            ret = min + "分" + (isShowSecond == 1 ?  sec + "秒":"") ;
        } else if(day == 0 && hour == 0 && min == 0 && sec > 0){
            ret = sec + "秒";
        }
        return ret;
    }


    public static String getDateByDaysStr(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        if (days > 0) {
            calendar.set(Calendar.HOUR_OF_DAY,23);
            calendar.set(Calendar.MINUTE,59);
            calendar.set(Calendar.SECOND,59);
        }else{
            calendar.set(Calendar.HOUR_OF_DAY,0);
            calendar.set(Calendar.MINUTE,0);
            calendar.set(Calendar.SECOND,0);
        }
        return getDay(calendar.getTime());
    }


    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     * @return
     */
    public static String getTime(Date date) {
        if (date == null) {
            return null;
        }
        return sdfTime.format(date);
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     * @return
     */
    public static String getTimeSimple(Date date) {
        if (date == null) {
            return null;
        }
        return sdfTime1.format(date);
    }



    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    /**
     * 获取YYYY-MM-DD格式
     * @return
     */
    public static String getDay() {
        return sdfDay.format(new Date());
    }

    /**
     * 获取YYYY-MM-DD格式
     * @return
     */
    public static String getDay(Date date) {
        return sdfDay.format(date);
    }
    /**
     * 格式化日期
     * @return
     */
    public static Date ConvertDateByformat(String date,String format) {
        DateFormat fmt = new SimpleDateFormat(format);
        try {
            return fmt.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 获取yyyyMMddHHmmss格式
     * @return
     */
    public static String getSdfTimes() {
        return sdfTimes.format(new Date());
    }


    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     * @return
     */
    public static String getSimpleTime(Date date) {
        return sdfSimpleTime.format(date);
    }
    public static String getSimpleDate(Date date) {
        return sdfDay.format(date);
    }
    /**
     * 格式化日期
     * @return
     */
    public static String fomatDateTime(String dateStr,String format) {
        DateFormat fmt = new SimpleDateFormat(format);
        try {
            Date date = fmt.parse(dateStr);
            return sdfTime.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 计算距离现在多久，非精确
     *
     * @param date
     * @return
     */
    public static String getTimeBefore(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        } else if (hour > 0) {
            r += hour + "小时";
        } else if (min > 0) {
            r += min + "分";
        } else if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算距离现在多久，精确
     *
     * @param date
     * @return
     */
    public static String getTimeBeforeAccurate(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        }
        if (hour > 0) {
            r += hour + "小时";
        }
        if (min > 0) {
            r += min + "分";
        }
        if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算两个日期相差的分钟
     * @param firstDate
     * @param secondDate
     * @return
     */
    public static long getMinutesBetween(Date firstDate, Date secondDate) {
        return Math.abs((secondDate.getTime() - firstDate.getTime()) / (1000 * 60));
    }


    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     * @param date1 时间参数 1 格式：1990-01-01 12:00:00
     * @param date2 时间参数 2 格式：2009-01-01 12:00:00
     * @return long[] 返回值为：{天, 时, 分, 秒}
     */
    public static long[] getDistanceTimes(Date date1, Date date2) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {
            long time1 = date1.getTime();
            long time2 = date2.getTime();
            long diff ;
            if(time1<time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long[] times = {day, hour, min, sec};
        return times;
    }


    /**
     * 两个时间相差的分钟数
     * @param date1 时间参数 1 格式：1990-01-01 12:00:00
     * @param date2 时间参数 2 格式：2009-01-01 12:00:00
     * @return int 两个时间相差的分钟数
     */
    public static int getDistanceMinutes(Date date1, Date date2) {
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        try {
            long time1 = date1.getTime();
            long time2 = date2.getTime();
            long diff ;
            if(time1<time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            day = diff / (24 * 60 * 60 * 1000);
            hour = (diff / (60 * 60 * 1000) - day * 24);
            min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long[] times = {day, hour, min, sec};

        //{天, 时, 分, 秒}
        long day1 = times[0];
        long hour1 = times[1];
        long minite1 = times[2];

        int totalMinute = (int) ((day1 * 24) + hour1) * 60 + (int) minite1;
        return totalMinute;
    }


    /**
     *  获取当前月份的 最后 、 第一天
     * @param month
     * @return
     */
    public static Date getDayOfMonth(int month, int isLast,int lastDay){
        Date ret = null;

        //当月一号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar1 = Calendar.getInstance();
        calendar1.set(Calendar.MONTH,month);
        if(lastDay > 0){
            calendar1.set(Calendar.DAY_OF_MONTH, lastDay);
        }else{
            calendar1.set(Calendar.DAY_OF_MONTH, 1);
        }
        calendar1.set(Calendar.HOUR_OF_DAY,0);
        calendar1.set(Calendar.MINUTE,0);
        calendar1.set(Calendar.SECOND,0);
        System.out.println("本月第一天: " + sdf.format(calendar1.getTime()));

        if(isLast == 0){
            ret = calendar1.getTime();
        }else{
            //当月最后一天
            Calendar calendar2 = Calendar.getInstance();
            calendar2.set(Calendar.MONTH, month);
            int maxCurrentMonthDay = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);
            if(lastDay > 0){
                calendar2.set(Calendar.DAY_OF_MONTH, lastDay);
            }else{
                calendar2.set(Calendar.DAY_OF_MONTH, maxCurrentMonthDay);
            }
            calendar2.set(Calendar.HOUR_OF_DAY,23);
            calendar2.set(Calendar.MINUTE,59);
            calendar2.set(Calendar.SECOND,59);
            System.out.println("本月最后一天: "+sdf.format(calendar2.getTime()));
            ret = calendar2.getTime();
        }
        return ret;
    }

    /**
     * 获取当前时间所在周的周一和周日的日期时间
     * @return
     */
    public static Map<String,Object> getWeekDate() {
        Map<String,Object> map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Calendar cal = Calendar.getInstance();
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if(dayWeek==1){
            dayWeek = 8;
        }

        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);

        cal.add(Calendar.DATE, 4 +cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        String weekEnd = sdf.format(sundayDate);

        map.put("beginDate", mondayDate);
        map.put("endDate", sundayDate);
        map.put("beginDateStr", weekBegin);
        map.put("endDateStr", weekEnd);
        return map;
    }


    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 当前季度的开始时间
     *
     * @return
     */
    public static Date getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                c.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                c.set(Calendar.MONTH, 4);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = sdfTime.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前季度的结束时间
     *
     * @return
     */
    public static Date getCurrentQuarterEndTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = sdfTime.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前季度的开始结束时间
     *
     * @return
     */
    public static Map<String,Object> getSeasonDate(){
        Map<String,Object> map = new HashMap();

        Date begin = getCurrentQuarterStartTime();
        Date end = getCurrentQuarterEndTime();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String beginDate = sdf.format(begin);

        String endDate = sdf.format(end);
        map.put("beginDate", begin);
        map.put("endDate", end);
        map.put("beginDateStr", beginDate);
        map.put("endDateStr", endDate);
        return map;
    }


    /**
     *  获取7天之前的所有日期
     * @return
     */
    public static List<String> getBeforeSevenDay(){
//        String [] arr = new String[7];
        List<String> arr = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = null;
        for (int i = 0;i < 7; i++){
            c = Calendar.getInstance();
            c.add(Calendar.DAY_OF_MONTH,  - i);
            arr.add(sdf.format(c.getTime()));
        }
        Collections.reverse(arr);
        return arr;
    }


    public static String getDayOfMonthStr(int month, int isLast,int lastDay){
        return getSdfTime(getDayOfMonth(month,isLast,lastDay));
    }

    /**
     * 获取yyyyMMddHHmmss格式
     * @return
     */
    public static String getSdfTime(Date date) {
        return sdfTime.format(date);
    }

    public static String getMinutesToHours(Long totalMinutes) {
        Long hours = totalMinutes / 60; // 计算小时
        Long minutes = totalMinutes % 60; // 计算剩余分钟
        if (hours > 0 && minutes > 0){
            return hours + "小时" + minutes + "分钟";
        }else if (minutes > 0){
            return minutes + "分钟";
        }else {
            return hours + "小时";
        }

    }

    /**
     *  获取指定月份的所有日期 date 2024-01-01
     * @return
     */
    public static List<String> getAllDayOfMonth(String date){
        String[] dateArr = date.split("-");
        // 获取指定月份的天数
        int year = Integer.parseInt(dateArr[0]); // 年份
        int month = Integer.parseInt(dateArr[1]); // 月份
        int daysInMonth = YearMonth.of(year, month).lengthOfMonth(); // 获取当月天数
        List<String> arr = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 循环获取每一天日期
        for (int day = 1; day <= daysInMonth; day++) {
            LocalDate localDate = LocalDate.of(year, month, day); // 构造日期对象
            arr.add(localDate.toString());
            System.out.println(date); // 输出日期
        }
        return arr;
    }

    /**
     * 添加分钟
     *
     * @param past
     * @return
     */
    public static Date getAfterDateMinute(int past) {
        Date currentDate = new Date();
        long fiveMinutesInMillis = past * 60 * 1000; // 5分钟的毫秒数
        long newTime = currentDate.getTime() + fiveMinutesInMillis;
        Date newDate = new Date();
        newDate.setTime(newTime);
        System.out.println("当前时间：" + currentDate);
        System.out.println("增加" + past + "分钟后的时间：" + newDate);
        return newDate;
    }

    public static void main(String[] args) {
        List<String> ss = getBeforeSevenDay();
        System.out.println(ss.toString());
    }
}
